/**************************************************************************************************
* Copyright (c) 2025 Advanced Micro Devices, Inc. All Rights Reserved.
* SPDX-License-Identifier: MIT
**************************************************************************************************/

/*************************************************************************************************/
/**
*
* @file	xasu_keywrap_client_example.c
* @addtogroup xasu_keywrap_client_example XilAsu Key wrap unwrap API Example Generic Usage
* @{
*
* @note
* This example illustrates the usage of ASU Key wrap unwrap APIs using below tests
* 	wrap the provided input data. The output result is then unwrapped
* 	back to get original data. The test fails, if unwrap operation does not
* 	produce the original data.
*
* MODIFICATION HISTORY:
* <pre>
* Ver   Who    Date     Changes
* ----- ------ -------- -------------------------------------------------
* 1.0   ss     02/24/25 Initial Release
*
* </pre>
**************************************************************************************************/

/*************************************** Include Files *******************************************/
#include "xil_cache.h"
#include "xil_util.h"
#include "xasu_keywrap.h"
#include "xasu_client.h"
#include "xasu_rsainfo.h"
#include "xasu_shainfo.h"
#include "xasu_aesinfo.h"

/************************************ Constant Definitions ***************************************/
#define XASU_KEYWRAP_RSA_4096_KEY_SIZE_IN_BYTES	(512U)	/**< RSA key size for 4096 bit data */
#define XASU_KEYWRAP_INPUT_SIZE_IN_BYTES	(31U)	/**< Key wrap unwrap input size */
#define XASU_RSA_OPTIONAL_DATA_SIZE_IN_BYTES	(2U)	/**< 512 bytes for 4096 bit data */
#define XASU_KEYWRAP_OUTPUT_SIZE_IN_BYTES	(552U)	/**< Key wrap unwrap output size */
#define XASU_CACHE_DISABLE
/************************************** Type Definitions *****************************************/

/*************************** Macros (Inline Functions) Definitions *******************************/

/************************************ Function Prototypes ****************************************/
static void XAsu_KeywrapunwrapCallBackRef(void *CallBackRef, u32 Status);

/************************************ Variable Definitions ***************************************/
static const u8 XAsu_RsaModulus[XASU_KEYWRAP_RSA_4096_KEY_SIZE_IN_BYTES] __attribute__ ((
		section (".data.XAsu_RsaModulus"))) = {
	0xCCU, 0x90U, 0xB4U, 0xB1U, 0xF1U, 0xC1U, 0xD3U, 0x9DU, 0x98U, 0xB1U, 0x34U, 0x49U, 0x92U,
	0xCDU, 0xFDU, 0xD1U, 0xCFU, 0x87U, 0x43U, 0x52U, 0xAFU, 0x9CU, 0x5CU, 0xFBU, 0x62U, 0xC9U,
	0xAAU, 0x7EU, 0xCAU, 0xFDU, 0x0EU, 0x2AU, 0xF9U, 0xBFU, 0x86U, 0xBCU, 0xDEU, 0xFDU, 0x10U,
	0x42U, 0x79U, 0xF2U, 0x18U, 0x6BU, 0xB1U, 0xCFU, 0x8DU, 0x66U, 0xDEU, 0xB0U, 0x64U, 0x1EU,
	0xB1U, 0x45U, 0x45U, 0x20U, 0x80U, 0xCCU, 0xCBU, 0x6AU, 0xADU, 0x1AU, 0x0AU, 0x2AU, 0xA9U,
	0xE2U, 0xA6U, 0x41U, 0xABU, 0xD3U, 0x3AU, 0xEDU, 0x34U, 0x71U, 0x2EU, 0x2DU, 0x08U, 0xF5U,
	0x16U, 0x7BU, 0x89U, 0xEBU, 0xBAU, 0xD5U, 0x86U, 0x33U, 0x0FU, 0x26U, 0x80U, 0x9FU, 0x3CU,
	0x98U, 0x11U, 0x62U, 0xDCU, 0x12U, 0x41U, 0xE9U, 0x7AU, 0x3CU, 0xD9U, 0x1BU, 0x0CU, 0xE5U,
	0x33U, 0x55U, 0x25U, 0x51U, 0xEFU, 0x2DU, 0xF2U, 0x3EU, 0x6EU, 0x7FU, 0xF9U, 0x76U, 0x86U,
	0x6CU, 0xA9U, 0x3CU, 0x04U, 0xFFU, 0xADU, 0xD1U, 0x9DU, 0x93U, 0xC1U, 0x04U, 0x4CU, 0x55U,
	0xABU, 0xFDU, 0xE7U, 0x71U, 0xAFU, 0xF5U, 0xA6U, 0xE1U, 0x51U, 0xE7U, 0xBAU, 0x4DU, 0x94U,
	0x22U, 0xD2U, 0x07U, 0x7BU, 0x64U, 0x11U, 0xC2U, 0x56U, 0xFAU, 0xBEU, 0x7CU, 0x1DU, 0x5FU,
	0x57U, 0x66U, 0x4EU, 0x88U, 0xD4U, 0x58U, 0x1FU, 0x12U, 0x07U, 0x65U, 0x77U, 0xA3U, 0x2AU,
	0xF4U, 0x8DU, 0xDEU, 0xDAU, 0x3CU, 0xA1U, 0x0DU, 0x41U, 0x3EU, 0x58U, 0x77U, 0x1EU, 0x59U,
	0x71U, 0xDBU, 0xD2U, 0xDDU, 0x48U, 0x20U, 0xE8U, 0xB9U, 0x09U, 0xB0U, 0xD5U, 0x95U, 0x26U,
	0xCFU, 0xAEU, 0x4FU, 0x31U, 0xDFU, 0x10U, 0xE7U, 0x7BU, 0x34U, 0x44U, 0x3EU, 0x2DU, 0x4EU,
	0x7EU, 0x9BU, 0xBAU, 0x9CU, 0xBDU, 0xB4U, 0xC9U, 0xD9U, 0x8AU, 0x09U, 0x74U, 0x75U, 0x3DU,
	0xD2U, 0x9FU, 0xDFU, 0x1AU, 0xE8U, 0x6AU, 0xA0U, 0x09U, 0xD3U, 0x66U, 0x04U, 0x8DU, 0xA8U,
	0x7BU, 0x4BU, 0x2EU, 0x3AU, 0x42U, 0xACU, 0xD7U, 0x24U, 0xFFU, 0x5FU, 0x9CU, 0x09U, 0x7FU,
	0xEFU, 0x22U, 0xA5U, 0x5AU, 0x7EU, 0x3BU, 0x63U, 0x36U, 0x38U, 0xF8U, 0xEBU, 0xFFU, 0xAEU,
	0xFDU, 0xDEU, 0x19U, 0xB6U, 0x38U, 0xC2U, 0x91U, 0x83U, 0x75U, 0x5FU, 0x86U, 0x9EU, 0xA7U,
	0x99U, 0xA1U, 0xC0U, 0x75U, 0x7EU, 0x43U, 0x8CU, 0xE7U, 0x4BU, 0x66U, 0x4CU, 0x3BU, 0xBBU,
	0x11U, 0x3EU, 0xF2U, 0x9DU, 0x84U, 0x4AU, 0x2FU, 0xACU, 0xBFU, 0x2CU, 0xC2U, 0xA9U, 0x97U,
	0xDCU, 0xC4U, 0x0FU, 0x09U, 0x2CU, 0xCCU, 0x1DU, 0x57U, 0xD6U, 0x34U, 0xB0U, 0x43U, 0xB9U,
	0xFBU, 0x45U, 0xC9U, 0x51U, 0xE8U, 0x87U, 0x39U, 0x90U, 0x49U, 0x81U, 0x1FU, 0x0EU, 0x6DU,
	0x1AU, 0x4FU, 0xC2U, 0x04U, 0xEEU, 0x69U, 0xF0U, 0x67U, 0xCEU, 0xDCU, 0x92U, 0xC5U, 0x8CU,
	0xCEU, 0x91U, 0x89U, 0x2CU, 0x56U, 0xFBU, 0xF8U, 0x70U, 0x8FU, 0xB9U, 0xCFU, 0xA0U, 0xBDU,
	0x9FU, 0x8AU, 0xF7U, 0xC5U, 0xEDU, 0xA1U, 0x57U, 0xD4U, 0x27U, 0x70U, 0x34U, 0xD5U, 0x59U,
	0x6AU, 0x93U, 0x48U, 0x11U, 0x00U, 0x02U, 0xD0U, 0x92U, 0xE6U, 0x1BU, 0xA3U, 0xFCU, 0xF8U,
	0x04U, 0x64U, 0x08U, 0x0BU, 0xDBU, 0x49U, 0x93U, 0xE3U, 0xB4U, 0x4DU, 0x68U, 0xEBU, 0x9EU,
	0xEAU, 0xABU, 0x19U, 0x36U, 0xA3U, 0xCFU, 0x39U, 0x6AU, 0xDDU, 0x24U, 0x1AU, 0x4EU, 0x70U,
	0x64U, 0xF4U, 0x0CU, 0x2CU, 0x54U, 0xCEU, 0xB3U, 0x78U, 0x53U, 0xEAU, 0x2DU, 0xB0U, 0xDBU,
	0xEEU, 0x58U, 0x86U, 0x00U, 0x42U, 0x99U, 0x8FU, 0xCFU, 0x2EU, 0x1FU, 0xCBU, 0xA5U, 0x60U,
	0x44U, 0xD4U, 0xBEU, 0x05U, 0x2CU, 0xD4U, 0x62U, 0xD8U, 0xB4U, 0x38U, 0xCBU, 0x80U, 0x38U,
	0x78U, 0x42U, 0x43U, 0xACU, 0xEBU, 0xA5U, 0xBDU, 0x05U, 0xFCU, 0x13U, 0xA7U, 0x2BU, 0x67U,
	0x82U, 0x02U, 0x4CU, 0x74U, 0x8EU, 0xAAU, 0xD0U, 0x28U, 0xD1U, 0x39U, 0x8CU, 0xEFU, 0x61U,
	0xB2U, 0xFFU, 0x60U, 0x41U, 0x83U, 0x99U, 0x81U, 0x4DU, 0xCFU, 0x81U, 0x7CU, 0xCCU, 0xECU,
	0xE3U, 0xF5U, 0xF1U, 0x17U, 0x2BU, 0x32U, 0xF2U, 0x46U, 0x8AU, 0xC4U, 0x93U, 0x20U, 0xC1U,
	0xD8U, 0xFCU, 0xC8U, 0x23U, 0x71U, 0xBFU, 0x37U, 0x85U, 0x00U, 0x7CU, 0xEDU, 0xB6U, 0x84U,
	0xABU, 0x45U, 0x00U, 0x39U, 0xA5U
};

static const u8 XAsu_RsaPrivateExp[XASU_KEYWRAP_RSA_4096_KEY_SIZE_IN_BYTES] __attribute__ ((
		section (".data.XAsu_RsaPrivateExp"))) = {
	0x07U, 0x31U, 0xDBU, 0xB9U, 0x1AU, 0x78U, 0xA7U, 0xB9U, 0xB6U, 0x42U, 0x1DU, 0x45U, 0xADU,
	0x2DU, 0x23U, 0x8DU, 0x3AU, 0x90U, 0x56U, 0x54U, 0xD5U, 0x2AU, 0x59U, 0xB6U, 0xD9U, 0xBDU,
	0xA0U, 0x0AU, 0x7FU, 0x97U, 0x30U, 0xE5U, 0x60U, 0x0DU, 0x55U, 0x6EU, 0xD5U, 0x24U, 0xEFU,
	0x6AU, 0x77U, 0x21U, 0x85U, 0xACU, 0x5BU, 0xFFU, 0xA1U, 0xC8U, 0x89U, 0x72U, 0x88U, 0xC2U,
	0xEFU, 0x97U, 0x31U, 0x1CU, 0x38U, 0x8BU, 0x7BU, 0x68U, 0x10U, 0x18U, 0x87U, 0x5DU, 0x02U,
	0xC6U, 0x9EU, 0xF4U, 0x56U, 0x57U, 0xC2U, 0x8DU, 0xCFU, 0x37U, 0x5FU, 0xD9U, 0x63U, 0xA4U,
	0x43U, 0x1BU, 0x2BU, 0x39U, 0xA8U, 0x43U, 0x94U, 0x49U, 0xBDU, 0x71U, 0xACU, 0x3AU, 0x6DU,
	0x86U, 0x27U, 0xAEU, 0x63U, 0x71U, 0x1CU, 0xF2U, 0x5AU, 0x43U, 0x43U, 0x9BU, 0x88U, 0xF3U,
	0x92U, 0xBFU, 0x9EU, 0xE5U, 0x67U, 0xD5U, 0x24U, 0xDCU, 0xFFU, 0x43U, 0xEFU, 0x01U, 0x35U,
	0x2FU, 0x23U, 0x30U, 0xA2U, 0x38U, 0x5FU, 0xE3U, 0xACU, 0x78U, 0x22U, 0xE4U, 0xC4U, 0xCEU,
	0x8AU, 0x93U, 0x0EU, 0x8DU, 0xD8U, 0x13U, 0x7AU, 0xC0U, 0x18U, 0x02U, 0x5FU, 0x72U, 0x15U,
	0x10U, 0xB8U, 0x74U, 0x5CU, 0xE9U, 0xA3U, 0x1AU, 0x43U, 0xB6U, 0xE3U, 0xF6U, 0x37U, 0x8EU,
	0x3FU, 0xE3U, 0xB0U, 0x45U, 0x6DU, 0xBAU, 0x7FU, 0xB5U, 0x41U, 0x9FU, 0x56U, 0xFAU, 0xDDU,
	0x2AU, 0xE6U, 0xC6U, 0x7CU, 0xC4U, 0x7FU, 0x21U, 0x99U, 0x36U, 0xD9U, 0x23U, 0xAFU, 0x64U,
	0x93U, 0xF5U, 0x98U, 0x50U, 0x02U, 0x16U, 0x6EU, 0x38U, 0xFBU, 0xD7U, 0x45U, 0x5BU, 0xCEU,
	0x96U, 0xA5U, 0x59U, 0xD1U, 0xB6U, 0x37U, 0xC0U, 0xFCU, 0x7BU, 0x55U, 0x1FU, 0x1EU, 0xB6U,
	0xD1U, 0x0BU, 0x27U, 0x20U, 0x16U, 0x28U, 0x02U, 0xA5U, 0x6DU, 0x0EU, 0x72U, 0x13U, 0x21U,
	0x8EU, 0x83U, 0xE2U, 0xF3U, 0xEEU, 0x52U, 0xB9U, 0xB8U, 0x3EU, 0xC0U, 0x2AU, 0xCEU, 0xD4U,
	0xABU, 0x29U, 0x74U, 0xC1U, 0xC5U, 0xD0U, 0x90U, 0x6CU, 0x93U, 0xB2U, 0xC8U, 0x29U, 0x29U,
	0x5FU, 0xBEU, 0xC7U, 0x34U, 0x0CU, 0x96U, 0x88U, 0x21U, 0xC3U, 0x05U, 0x1DU, 0x3EU, 0x31U,
	0x3BU, 0xDFU, 0x6FU, 0x57U, 0xF1U, 0xD4U, 0x9CU, 0x6CU, 0x48U, 0x8FU, 0xCDU, 0x88U, 0xE4U,
	0xC0U, 0x8EU, 0xDAU, 0x79U, 0x27U, 0x50U, 0xA8U, 0x7CU, 0xB9U, 0x38U, 0xA3U, 0x93U, 0x67U,
	0x36U, 0x35U, 0x35U, 0xB3U, 0x2AU, 0x4DU, 0x16U, 0x96U, 0x47U, 0x98U, 0x27U, 0xEFU, 0xDEU,
	0x23U, 0xE6U, 0xFBU, 0x4BU, 0xAFU, 0x7AU, 0xB1U, 0x9BU, 0x7CU, 0x05U, 0xBEU, 0x0EU, 0xCEU,
	0x69U, 0x53U, 0xF0U, 0x76U, 0xC1U, 0x89U, 0xCCU, 0xF2U, 0xCAU, 0x2CU, 0xBBU, 0xA4U, 0xFEU,
	0x3CU, 0x3DU, 0xAFU, 0xBCU, 0x25U, 0x4AU, 0x53U, 0x4BU, 0xE9U, 0x85U, 0x55U, 0xF1U, 0x79U,
	0x70U, 0xDFU, 0x57U, 0x23U, 0x55U, 0x7DU, 0x7AU, 0x5CU, 0xA7U, 0xEEU, 0xFBU, 0x00U, 0x35U,
	0x1EU, 0xE3U, 0xF1U, 0xFDU, 0x3EU, 0x94U, 0x70U, 0x88U, 0x91U, 0xFAU, 0xC6U, 0xCBU, 0x05U,
	0xE1U, 0xCDU, 0x7DU, 0xD1U, 0xE3U, 0x2BU, 0x7FU, 0xB4U, 0x64U, 0x1CU, 0x94U, 0x1EU, 0xC2U,
	0x55U, 0x6CU, 0x78U, 0x22U, 0x27U, 0x90U, 0xBAU, 0x33U, 0x0EU, 0xADU, 0x5DU, 0x55U, 0xD9U,
	0xDFU, 0x7BU, 0x83U, 0xA5U, 0x2BU, 0x4FU, 0xA0U, 0x36U, 0x3CU, 0x67U, 0xDDU, 0xC4U, 0x00U,
	0x50U, 0x90U, 0x12U, 0xE1U, 0x8AU, 0x65U, 0x35U, 0x13U, 0x9EU, 0xB2U, 0x0CU, 0xE4U, 0xEAU,
	0x51U, 0x2FU, 0xCDU, 0xAEU, 0x35U, 0x41U, 0x1EU, 0xFAU, 0x5AU, 0x6CU, 0xB6U, 0xC1U, 0xA7U,
	0xFEU, 0x69U, 0x6FU, 0x7DU, 0x50U, 0xFCU, 0xABU, 0x5FU, 0xADU, 0x0CU, 0x2BU, 0x58U, 0xF6U,
	0xB3U, 0x33U, 0x1FU, 0xF4U, 0x3AU, 0xDAU, 0x89U, 0xD3U, 0x0EU, 0x79U, 0x7BU, 0x31U, 0x8EU,
	0x15U, 0x84U, 0xECU, 0x2CU, 0x05U, 0x2FU, 0xA9U, 0x52U, 0xF6U, 0x59U, 0x94U, 0xBFU, 0xC0U,
	0x4BU, 0xCDU, 0x40U, 0xFBU, 0x24U, 0x44U, 0x0FU, 0x76U, 0x11U, 0xE8U, 0xD1U, 0xE3U, 0x13U,
	0x26U, 0xEFU, 0xFAU, 0xA9U, 0xE3U, 0xDBU, 0x73U, 0x29U, 0x80U, 0x4DU, 0x61U, 0x74U, 0x3CU,
	0x12U, 0x50U, 0xFDU, 0xDDU, 0xEAU, 0x72U, 0xE4U, 0x88U, 0x8BU, 0x20U, 0x1AU, 0x3BU, 0x36U,
	0xE8U, 0xB8U, 0x98U, 0x55U, 0xCDU
};

static const u8 XAsu_KeywrapInput[XASU_KEYWRAP_INPUT_SIZE_IN_BYTES] __attribute__ ((
        section (".data.XAsu_KeywrapInput"))) = {
	0x2cU, 0xe9U, 0x3aU, 0x23U, 0x22U, 0x69U, 0xfeU, 0x10U, 0x59U, 0xcaU, 0x99U, 0x2aU, 0xd8U,
        0xb7U, 0x07U, 0xfeU, 0x2eU, 0x72U, 0x33U, 0xe5U, 0xabU, 0xb3U, 0xdeU, 0x0dU, 0x7fU, 0xf7U,
        0x25U, 0x2aU, 0x78U, 0xc9U, 0x9dU
};

static const char XAsu_RsaOpt[XASU_RSA_OPTIONAL_DATA_SIZE_IN_BYTES + 1U] __attribute__ ((
        section (".data.XAsu_RsaOpt"))) = "HI";

static const u32 XAsu_RsaPublicExp
__attribute__ ((section (".data.XAsu_RsaPublicExp"))) = 0x1000100U;

static u8 XAsu_KeyWrapWrappedOutput[XASU_KEYWRAP_OUTPUT_SIZE_IN_BYTES] __attribute__ ((
        section (".data.XAsu_KeyWrapWrappedOutput")));
static u8 XAsu_KeyWrapUnwrappedOutput[XASU_KEYWRAP_INPUT_SIZE_IN_BYTES] __attribute__ ((
        section (".data.XAsu_KeyWrapUnwrappedOutput")));

static u32 XAsu_KeyWrapOutputLen __attribute__ ((section (".data.XAsu_KeyWrapOutputLen")));
static u32 XAsu_KeyWrapUnwrapOutputLen
__attribute__ ((section (".data.XAsu_KeyWrapUnwrapOutputLen")));

static u8 Notify = 0; /**< To notify the call back from client library */
volatile u32 ErrorStatus = XST_FAILURE; /**< Status variable to store the error returned from
						server. */
/************************************ Function Definitions ***************************************/

/*************************************************************************************************/
/**
 * @brief	Main function to call the XAsu_Keywrap() and XAsu_Keyunwrap() API's.
 *
 * @return
 *		- XST_SUCCESS if example runs successfully.
 *		- ErrorCode if the example fails.
 *
 *************************************************************************************************/
int main(void)
{
	s32 Status = XST_FAILURE;
	XAsu_KeyWrapParams KwpunwpClientParam;
	XAsu_ClientParams ClientParam = {0U};
	XAsu_RsaPubKeyComp PubKeyParam;
	XAsu_RsaPvtKeyComp PvtKeyParam;
	XMailbox MailboxInstance;

#ifdef XASU_CACHE_DISABLE
	Xil_DCacheDisable();
#endif

	/* Initialize client parametrs */
	ClientParam.Priority = XASU_PRIORITY_HIGH;
	ClientParam.CallBackFuncPtr = (XAsuClient_ResponseHandler)((void *)XAsu_KeywrapunwrapCallBackRef);
	ClientParam.CallBackRefPtr = (void *)&ClientParam;

	/** Initialize mailbox instance. */
	Status = (s32)XMailbox_Initialize(&MailboxInstance, XPAR_XIPIPSU_0_BASEADDR);
	if (Status != XST_SUCCESS) {
		xil_printf("Mailbox initialize failed: %08x \r\n", Status);
		goto END;
	}

	/* Initialize the client instance */
	Status = XAsu_ClientInit(&MailboxInstance);
	if (Status != XST_SUCCESS) {
		xil_printf("Client initialize failed:%08x \r\n", Status);
		goto END;
	}

	/* Copy RSA key parameters for RSA OAEP operation */
	PubKeyParam.Keysize = XASU_KEYWRAP_RSA_4096_KEY_SIZE_IN_BYTES;
	PubKeyParam.PubExp = XAsu_RsaPublicExp;

	Xil_SMemCpy(PubKeyParam.Modulus, XASU_KEYWRAP_RSA_4096_KEY_SIZE_IN_BYTES, XAsu_RsaModulus,
		    XASU_KEYWRAP_RSA_4096_KEY_SIZE_IN_BYTES, XASU_KEYWRAP_RSA_4096_KEY_SIZE_IN_BYTES);

	PvtKeyParam.PubKeyComp = PubKeyParam;
	PvtKeyParam.PrimeCompOrTotientPrsnt = 0U;

	Xil_SMemCpy(PvtKeyParam.PvtExp, XASU_KEYWRAP_RSA_4096_KEY_SIZE_IN_BYTES, XAsu_RsaPrivateExp,
		    XASU_KEYWRAP_RSA_4096_KEY_SIZE_IN_BYTES, XASU_KEYWRAP_RSA_4096_KEY_SIZE_IN_BYTES);

	/* Key wrap parameters structure initialization for encryption */
	ErrorStatus = XST_FAILURE;
	KwpunwpClientParam.InputDataAddr = (u64)(UINTPTR)XAsu_KeywrapInput;
	KwpunwpClientParam.OutputDataAddr = (u64)(UINTPTR)XAsu_KeyWrapWrappedOutput;
	KwpunwpClientParam.ExpoCompAddr = 0U;
	KwpunwpClientParam.KeyCompAddr = (u64)(UINTPTR)&PubKeyParam;
	KwpunwpClientParam.OptionalLabelAddr = (u64)(UINTPTR)XAsu_RsaOpt;
	KwpunwpClientParam.InputDataLen = XASU_KEYWRAP_INPUT_SIZE_IN_BYTES;
	KwpunwpClientParam.RsaKeySize = XASU_KEYWRAP_RSA_4096_KEY_SIZE_IN_BYTES;
	KwpunwpClientParam.OptionalLabelSize = XASU_RSA_OPTIONAL_DATA_SIZE_IN_BYTES;
	KwpunwpClientParam.OutuputDataLen = XASU_KEYWRAP_OUTPUT_SIZE_IN_BYTES;
	KwpunwpClientParam.ActualOutuputDataLenAddr = (u64)(UINTPTR)&XAsu_KeyWrapOutputLen;
	KwpunwpClientParam.AesKeySize = XASU_AES_KEY_SIZE_256_BITS;
	KwpunwpClientParam.ShaType = XASU_SHA2_TYPE;
	KwpunwpClientParam.ShaMode = XASU_SHA_MODE_SHA256;

	/* Perform key wrap operation */
	Status = XAsu_KeyWrap(&ClientParam, &KwpunwpClientParam);
	if (Status != XST_SUCCESS) {
		xil_printf("\r\n Key wrap operation Status = %08x", Status);
		goto END;
	}
	while (!Notify);
	Notify = 0;
	if (XAsu_KeyWrapOutputLen != XASU_KEYWRAP_OUTPUT_SIZE_IN_BYTES) {
		Status = XST_FAILURE;
		goto END;
	}
	if (ErrorStatus != XST_SUCCESS) {
		goto END;
	}

	ClientParam.Priority = XASU_PRIORITY_HIGH;
	ClientParam.CallBackFuncPtr = (XAsuClient_ResponseHandler)((void *)XAsu_KeywrapunwrapCallBackRef);
	ClientParam.CallBackRefPtr = (void *)&ClientParam;

	/* Key unwrap parameters structure initialization for encryption */
	ErrorStatus = XST_FAILURE;
	KwpunwpClientParam.InputDataAddr = (u64)(UINTPTR)XAsu_KeyWrapWrappedOutput;
	KwpunwpClientParam.OutputDataAddr = (u64)(UINTPTR)XAsu_KeyWrapUnwrappedOutput;
	KwpunwpClientParam.ExpoCompAddr = 0U;
	KwpunwpClientParam.KeyCompAddr = (u64)(UINTPTR)&PvtKeyParam;
	KwpunwpClientParam.OptionalLabelAddr = (u64)(UINTPTR)XAsu_RsaOpt;
	KwpunwpClientParam.InputDataLen = XASU_KEYWRAP_OUTPUT_SIZE_IN_BYTES;
	KwpunwpClientParam.RsaKeySize = XASU_KEYWRAP_RSA_4096_KEY_SIZE_IN_BYTES;
	KwpunwpClientParam.OptionalLabelSize = XASU_RSA_OPTIONAL_DATA_SIZE_IN_BYTES;
	KwpunwpClientParam.OutuputDataLen = XASU_KEYWRAP_INPUT_SIZE_IN_BYTES;
	KwpunwpClientParam.ActualOutuputDataLenAddr = (u64)(UINTPTR)&XAsu_KeyWrapUnwrapOutputLen;
	KwpunwpClientParam.AesKeySize = XASU_AES_KEY_SIZE_256_BITS;
	KwpunwpClientParam.ShaType = XASU_SHA2_TYPE;
	KwpunwpClientParam.ShaMode = XASU_SHA_MODE_SHA256;

	/* Perform key unwrap operation */
	Status = XAsu_KeyUnwrap(&ClientParam, &KwpunwpClientParam);
	if (Status != XST_SUCCESS) {
		xil_printf("\r\n Decrypt operation Status = %08x", Status);
		goto END;
	}
	while (!Notify);
	Notify = 0;
	if (XAsu_KeyWrapUnwrapOutputLen != XASU_KEYWRAP_INPUT_SIZE_IN_BYTES) {
		Status = XST_FAILURE;
		goto END;
	}
	if (ErrorStatus != XST_SUCCESS) {
		goto END;
	}

	/** Compare generated unwrapped message with expected input. */
	Status = Xil_SMemCmp_CT(XAsu_KeywrapInput, XASU_KEYWRAP_INPUT_SIZE_IN_BYTES, XAsu_KeyWrapUnwrappedOutput,
		XASU_KEYWRAP_INPUT_SIZE_IN_BYTES, XASU_KEYWRAP_INPUT_SIZE_IN_BYTES);
	if (Status != XST_SUCCESS) {
		xil_printf("ASU Key Wrap Unwrap Example Failed at Unwrapped data Comparison \r\n");
	}

END:
	if (Status != XST_SUCCESS) {
		xil_printf("\r\n Key wrap unwrap client example failed with Status = %08x", Status);
	} else if (ErrorStatus != XST_SUCCESS) {
		xil_printf("\r\n Key wrap unwrap client example failed with error from server = %08x", ErrorStatus);
	} else {
		xil_printf("\r\n Successfully ran Key wrap unwrap client example ");
	}

	return Status;
}

/*************************************************************************************************/
/**
 * @brief	Call back function which will be registered with library to notify the completion
 * 		of request
 *
 * @param	CallBackRef	Pointer to the call back reference.
 * @param	Status		Status of the request will be passed as an argument during callback
 * 			- 0 Upon success
 * 			- Error code from ASUFW application upon any error
 *
 *************************************************************************************************/
  static void XAsu_KeywrapunwrapCallBackRef(void *CallBackRef, u32 Status)
 {
	(void)CallBackRef;

	ErrorStatus = Status;
	/* Update the variable to notify the callback */
	Notify = 1U;

 }